<?php


namespace app\common\cachemodel;


use app\common\lib\PushQueue;
use app\common\lib\Util;
use app\common\model\BaseCache;
use \Exception;
use think\Env;
use think\Log;
use traits\model\SoftDelete;
use XznsTools\cache\CacheManage;

/**
 * 合盘报告模型
 * Class SynastryReport
 * @package app\common\cachemodel
 */
class ZlSynastryReport extends BaseCache
{
    protected $table = 'wechat_backup_07_18_14_43_00.zl_synastry_report';

    protected $cacheModel = 'user.synastry_report';

    use SoftDelete;

    protected $deleteTime = 'delete_time';

    /**
     * 更新合盘报告数据
     * @param $data
     * @param $id
     * @return bool
     * @throws Exception
     */
    public function UpdateData($data, $id): bool
    {
        try
        {
            $this->where('id', $id)->update($data);
        }
        catch (Exception $e)
        {
            Log::write("更新合盘报告ID【{$id}】数据失败：" . $e->getMessage() . '[ ' . $e->getFile() . '：' . $e->getLine() . ' ]', 'error', true);

            return false;
        }

        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $id)->rmCache();

        return true;
    }

    /**
     * 合盘报告 入队 + 结果数据写入
     * @param int $uid
     * @param int $unlcok_gid 解锁商品
     * @param array $extend
     * @param string $orderId
     * @param null $queueDelay 队列等待时长
     * @throws Exception
     */
    public function SaveQueue(int $uid, int $unlcok_gid, array $extend, string $orderId, $queueDelay = NULL): void
    {
        $recodeInfos = (new Recode())->batchGetInfoByIds([$extend['rid1'], $extend['rid2']], ['id', 'name', 'type', 'year', 'month', 'day', 'hour', 'minute', 'timezone', 'birth_country', 'birth_province', 'birth_city', 'live_country', 'live_province', 'live_city', 'comments', 'isself', 'long_deg', 'long_min', 'ew', 'lat_deg', 'lat_min', 'ns', 'avatar', 'is_summer', 'uid', 'sun', 'moon', 'asc',]);

        foreach ($recodeInfos as $rid => $recodeInfoItem)
        {
            $utilModel = new Util();
            $recodeInfos[$rid]['sun'] = mb_substr($utilModel->recodeAstro($recodeInfoItem['sun']), 0, 2);
            $recodeInfos[$rid]['moon'] = mb_substr($utilModel->recodeAstro($recodeInfoItem['moon']), 0, 2);
            $recodeInfos[$rid]['asc'] = mb_substr($utilModel->recodeAstro($recodeInfoItem['asc']), 0, 2);
        }

        $recodeData = [
            'recode1' => $recodeInfos[$extend['rid1']],
            'recode2' => $recodeInfos[$extend['rid2']],
        ];

        $recodeInfosStr = \GuzzleHttp\json_encode($recodeData, JSON_UNESCAPED_UNICODE);

        $time = time();

        // 计算 合盘报告计算开始时间 开始--------------------
        // $year = date("Y", $time);
        // $month = date('m', $time);
        // // 下月1号0点时间戳
        // $nextMonthStarttime = strtotime(date('Y-m-d', mktime(0, 0, 0, +($month + 1), 1, $year)));
        // // 距离下个月1号小于等于10天时，推运时间取下个月
        // if ($nextMonthStarttime - $time <= 86400 * 10)
        // {
        //     $startTime = $nextMonthStarttime;
        // } else
        // {
        //     $startTime = strtotime(date('Y-m-d', mktime(0, 0, 0, $month, 1, $year)));
        // }
        // 计算 合盘报告计算开始时间 结束--------------------
        $data = [
            'uid' => $uid,
            'srid' => $extend['srid'],
            'relation_id' => $extend['relation_id'],
            'gid' => $unlcok_gid,
            'rid1' => (int)$extend['rid1'],
            'rid2' => (int)$extend['rid2'],
            'give_id' => 0,
            'order_num' => $orderId,
            'status' => 1,
            'recode_info' => $recodeInfosStr,
            'start_time' => $extend['start_time'],
            'create_time' => $time,
        ];

        try
        {
            $unlockTimeData = [
                'uid' => $uid,
                'srid' => $extend['srid'],
                'relation_id' => $extend['relation_id'],
                'rid1' => $data['rid1'],
                'rid2' => $data['rid2'],
                'order_num' => $orderId,
                'status' => 1,
                'create_time' => $time,
            ];

            (new ZlSynastryReportUnlockTimeInfo())->saveData($unlockTimeData, (int)$extend['start_time'], (int)date('Ym', strtotime($extend['expire_time'] . ' -1month', $extend['start_time'])));

            $id = $this->insertGetId($data);
        }
        catch (Exception $e)
        {
            Log::write($orderId . '添加合盘报告数据失败：' . $e->getMessage() . '[ ' . $e->getFile() . '：' . $e->getLine() . ' ]', 'error', true);

            return;
        }
        // 删除合盘报告缓存
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, "{$uid}:{$extend['srid']}")->rmCache('list');
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, "{$uid}:{$extend['srid']}:{$extend['rid1']}_{$extend['rid2']}")->rmCache('list');

        //删除档案解锁的合盘报告订单编号缓存
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid)->setListKeyType($extend['rid1'])->rmCache('list');
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid)->setListKeyType($extend['rid2'])->rmCache('list');
        //本命预测入队
        (new PushQueue())->SynastryReport($uid, (int)$id, $data['rid1'], $queueDelay);
    }


    /**
     * 获取订单相关合盘报告备份档案信息
     * @param string $order_id
     * @return array|bool|mixed|string
     * @throws Exception
     */
    public function getOrderRecodeBackRecode($order_id)
    {
        return CacheManage::getInstance()->setCacheConfig($this->cacheModel)->setCacheKeyDetail('details2', $order_id)->getDataAndSet(function () use ($order_id)
        {
            try
            {
                return $this
                    ->where(['order_num' => $order_id])
                    ->column('recode_info', 'id');
            }
            catch (\Exception $e)
            {
                return [];
            }
        }, [], 'details2');
    }

    /**
     * 获取档案解锁的合盘报告订单编号
     * @param $uid
     * @param $rid
     * @return array|mixed
     * @throws Exception
     */
    public function getRidSynastryReportOrderIds($uid, $rid)
    {
        return CacheManage::getInstance()->setCacheConfig($this->cacheModel, $uid)->setListKeyType($rid)->ZsGetIocData('list', function () use ($uid, $rid)
        {
            try
            {
                $orderIds = $this->where(['uid' => $uid])->where(function ($query) use ($rid)
                {
                    $query->whereOr(['rid1' => $rid, 'rid2' => $rid]);
                })->column('order_num', 'order_num');

                return array_flip_key_value($orderIds);
            }
            catch (Exception $e)
            {
                return [];
            }
        });
    }

    /**
     * 获取用户解锁合盘报告ID
     * @param int $uid
     * @param int $rid1
     * @param int $rid2
     * @param int $srid
     * @return array|bool|mixed
     * @throws Exception
     */
    public function getSynastryReportIds(int $uid, int $rid1, int $rid2, int $srid): array
    {
        $key = $rid2 ? "{$uid}:{$srid}:{$rid1}_{$rid2}" : "{$uid}:{$srid}"; // 判断获取全部合盘报告 还是 双人合盘报告

        $reportIdsData = CacheManage::getInstance()->setCacheConfig($this->cacheModel, $key)->setPage(-1)->setSort('desc')->setListKeyType(0)// 类型 用于分页 例如 0全部 1待支付 已支付 //
        ->getListPageDataIds(function () use ($uid, $rid1, $rid2, $srid)
        {
            try
            {
                $this->where(['uid' => $uid, 'srid' => $srid]);
                if ($rid2)
                {
                    $this->where(['rid1' => $rid1, 'rid2' => $rid2]);
                }

                $ids = $this->order('id desc')->column('id');
                $resData = [];
                foreach ($ids as $id)
                {
                    $resData[$id] = ['id' => $id];
                }

                return $resData;
            }
            catch (Exception $e)
            {
                return [];
            }
        }, 'id', 0);

        return array_keys($reportIdsData['data']);
    }

    /**
     * 获取当前两个档案 是否有解锁过的 合盘报告
     * @param int $uid
     * @param int $rid1
     * @param int $rid2
     * @param int $srid
     * @return bool
     * @throws Exception
     */
    public function getUserHasReportUnlockStatus(int $uid, int $rid1, int $rid2, int $srid): bool
    {
        $unlockIds = $this->getSynastryReportIds($uid, $rid1, $rid2, $srid);

        return $unlockIds ? true : false;
    }

    /**
     * 获取合盘报告列表数据
     * @param int $uid
     * @param int $rid1
     * @param int $rid2
     * @param int $srid
     * @return array
     * @throws Exception
     */
    public function getSynastryReportList(int $uid, int $rid1, int $rid2, int $srid, int $selfRid): array
    {
        $ids = $this->getSynastryReportIds($uid, $rid1, $rid2, $srid);

        $resData = [];

        if ($ids)
        {
            $reportListData = $this->batchGetInfoByIds($ids, ['id', 'relation_id', 'content', 'start_time', 'gid', 'create_time', 'rid1_name', 'rid2_name', 'rid1_avatar', 'rid2_avatar', 'status', 'rid1', 'rid2']);
            $synastryReportConfig = (new Goods())->GoodsTypeInfo(17)[$srid];
            $domain = Env::get('host.domain');
            foreach ($ids as $id)
            {
                if (!isset($reportListData[$id]))
                {
                    continue;
                }

                if ((int)$reportListData[$id]['status'] === 2)
                {   // 计算成功
                    $target = 'link';
                    $link = "{$domain}/web/synastry_report/index?id={$id}&zhunle_not_show_nav=1&zhunle_nav_text_color=1&need_auth=1";
                    $status = 2;
                } else
                {   // 计算中
                    $target = 'local';
                    $link = 'empty';
                    $status = 1;
                }
                $expireTime = $synastryReportConfig['good_list'][$reportListData[$id]['gid']]['expire_time'];
                $resData[] = [
                    'id' => (int)$reportListData[$id]['id'],
                    'name1' => $selfRid == $reportListData[$id]['rid1'] ? '自己' : ($reportListData[$id]['rid1_name'] ?? ''),
                    'name2' => $selfRid == $reportListData[$id]['rid2'] ? '自己' : ($reportListData[$id]['rid2_name'] ?? ''),
                    'avatar1' => $reportListData[$id]['rid1_avatar'] ?? '',
                    'avatar2' => $reportListData[$id]['rid2_avatar'] ?? '',
                    'relation' => '当前关系：' . ($synastryReportConfig['relation_list'][$reportListData[$id]['relation_id']]['name'] ?? '未知'),
                    'status' => $status,
                    'time_range' => '计算时段：' . date('Y.m.d', $reportListData[$id]['start_time']) . '-' . date('Y.m.d', strtotime($expireTime, $reportListData[$id]['start_time'])),
                    'target' => $target,
                    'link' => $link,
                ];
            }
        }

        return $resData;
    }

    /**
     * 通过数据库 获取合盘报告数据
     * @param $ids
     * @param $type
     * @param $sortType
     * @return array
     */
    public function getInfoByIdsInData($ids, $type, $sortType): array
    {
        try
        {
            $data = $this->whereIn('id', $ids)->column('uid,relation_id,rid1,rid2,gid,srid,give_id,order_num,content,status,recode_info,create_time,start_time', 'id');

            if (!empty($data))
            {
                foreach ($data as $reportId => $reportData)
                {
                    $recodeInfos = \GuzzleHttp\json_decode($reportData['recode_info'], true);
                    $reportData['rid1_name'] = $recodeInfos['recode1']['name'];
                    $reportData['rid2_name'] = $recodeInfos['recode2']['name'];
                    $reportData['rid1_avatar'] = $recodeInfos['recode1']['avatar'];
                    $reportData['rid2_avatar'] = $recodeInfos['recode2']['avatar'];
                    $reportData['rid1_astr_info'] = "日{$recodeInfos['recode1']['sun']}-月{$recodeInfos['recode1']['moon']}-升{$recodeInfos['recode1']['asc']}";
                    $reportData['rid2_astr_info'] = "日{$recodeInfos['recode2']['sun']}-月{$recodeInfos['recode2']['moon']}-升{$recodeInfos['recode2']['asc']}";
                    $data[$reportId] = $reportData;
                }
            } else
            {
                $idsString = json_encode($ids);
                Log::write("合盘报告【{$idsString}】数据不存在或已被删除", 'error');
            }
        }
        catch (Exception $e)
        {
            Log::write('合盘报告获取数据：' . $e->getMessage() . '[' . $e->getFile() . ':' . $e->getLine() . ']', 'error', true);
            $data = [];
        }
        return $data;
    }

    /**
     * 合盘报告删除
     * @param int $uid
     * @param int $id
     * @param int $rid1
     * @param int $rid2
     * @param int $srid
     * @return bool
     * @throws Exception
     */
    public function reportDel(int $uid, int $id, int $rid1, int $rid2, int $srid): bool
    {
        try
        {
            $this::destroy($id);
        }
        catch (Exception $e)
        {
            return false;
        }
        // 删除合盘报告列表缓存
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, "{$uid}:{$srid}")->rmCache('list');
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, "{$uid}:{$srid}:{$rid1}_{$rid2}")->rmCache('list');
        // 删除合盘报告详情缓存
        CacheManage::getInstance()->setCacheConfig($this->cacheModel, $id)->rmCache();

        return true;
    }
}
